// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Lu Rong
// Date   : 2005-02-22

#include "stdafx.h"
#include "tm_cstrench.h"
#include "msvr_room_cs15.h"
#include "msvr_cstrench.h"
#include "msvr_user.h"
#include <common/svr_base/svr_server.h>

namespace JoyServer
{

// added by lr 2005-05-31
class CJoyCSTrenchDataMsg : public CJoyUserSetMsg
{
public:
	virtual void OnExecute();
	virtual void OnExecute(CJoyUser* pUser);

	CJoyCSTrenchDataMsg() {}
	virtual ~CJoyCSTrenchDataMsg() {}
};

void CJoyCSTrenchDataMsg::OnExecute()
{
	CJoyUserSetMsgQueue* pQueue = GetQueue();
    CJoyUserSet* pUserSet = pQueue->GetUserSet();

	CJoyMainRoom_CS15 *room = static_cast<CJoyMainRoom_CS15 *>(pUserSet);

    CJoyAutoCS gate(pUserSet->m_userLock);

	CJoyMainRoom_CS15::CCSTrenchList &trenchList = room->m_trenchlist;
	CJoyMainRoom_CS15::CCSSvrIdList &csSvrList = room->m_csSvrIdList;

	if (!trenchList.IsEmpty())
	{	
		POSITION pos = trenchList.GetStartPosition();
		UINT nKey;
		CJoyCSTrench *pTrench = NULL;
		while (pos != NULL)
		{
			trenchList.GetNextAssoc(pos, nKey, pTrench);

			if (pTrench->m_bmodify)
			{
				// added by lr 2005-05-24
				pTrench->SortPlayers();

				CJoyTransmitData* data = pTrench->BuildCSTrench();
				room->BroadcastMsg(data, csSvrList);

				data->Release();

				pTrench->m_bmodify = false;

				if (!pTrench->m_active)
				{
					UINT nMapCount = 0;
					if (csSvrList.Lookup(pTrench->m_srcUser, nMapCount))
					{
						--nMapCount;
						csSvrList[pTrench->m_srcUser] = nMapCount;
						if (nMapCount <= 0)
							csSvrList.RemoveKey(pTrench->m_srcUser);
					}

					trenchList.RemoveKey(pTrench->m_trenchId);
					delete pTrench;					
				}
			}			
		}
	}
}

void CJoyCSTrenchDataMsg::OnExecute(CJoyUser* pUser)
{
	pUser;
}

// class CJoyTmCSTrench
CJoyTmCSTrench::CJoyTmCSTrench()
{
	m_room = NULL;
	m_elapse = 30000;
}

CJoyTmCSTrench::~CJoyTmCSTrench()
{
}

void CJoyTmCSTrench::OnExecute()
{
	CJoyMainRoom_CS15 *room = static_cast<CJoyMainRoom_CS15 *>(m_room);

	CJoyCSTrenchDataMsg *pMsg = new CJoyCSTrenchDataMsg();
	room->QueueMsg(pMsg);
}

bool CJoyTmCSTrench::Create(CJoyMainRoom *pRoom)
{
	m_room = pRoom;

	if (!__super::Create(&pRoom->m_server->m_timer, m_elapse))
	{
		return false;
	}

	return true;
}

void CJoyTmCSTrench::Destroy()
{
	__super::Destroy();
}

bool CJoyMainRoom_CS15::Create(CJoyMainServer* pServer, CJoyDbSession& onlineSess, CJoyDbCommand& record, UINT roomId, UINT gameId)
{
	if(!__super::Create(pServer, onlineSess, record, roomId, gameId))
    {
        return false;
    }

	if (!InitTimingTask())
	{
		Destroy();
		return false;
	}

    return true;
}

void CJoyMainRoom_CS15::Destroy()
{
	FreeTimingTask();
	__super::Destroy();	
}

bool CJoyMainRoom_CS15::OnUserEnter(CJoyUser* pUser)
{
	if (!__super::OnUserEnter(pUser))
		return false;

	// added by lr 2005-05-18
	//CJoyAutoCS gate(m_trenchLock);

	if (!m_trenchlist.IsEmpty())
	{	
		POSITION pos = m_trenchlist.GetStartPosition();
		while (pos != NULL)
		{
			UINT nKey;
			CJoyCSTrench *pTrench = NULL;
			m_trenchlist.GetNextAssoc(pos, nKey, pTrench);

			if (pTrench->m_active)
			{
				// added by lr 2005-05-24
				pTrench->SortPlayers();

				CJoyTransmitData* data = pTrench->BuildCSTrench();
				pUser->SendMsg(data);	// added by lr 2005-05-17

				data->Release();
			}
		}
	}
	return true;
}

void CJoyMainRoom_CS15::OnUserLeave(CJoyUser* pUser)
{
	{
	// added by lr 2005-05-18
	//CJoyAutoCS gate(m_trenchLock);

	UINT nMapCount = 0;
	if (m_csSvrIdList.Lookup(pUser->m_userId, nMapCount))
	{
		POSITION pos = m_trenchlist.GetStartPosition();
		while (pos != NULL)
		{
			UINT trench_id = 0;
			CJoyCSTrench *pTrench = NULL;
			m_trenchlist.GetNextAssoc(pos, trench_id, pTrench);

			if (pTrench->m_srcUser == pUser->m_userId)
			{
				pTrench->m_active = false;
				pTrench->m_bmodify = true;
			}
		}
	}
	}

	__super::OnUserLeave(pUser);
}

bool CJoyMainRoom_CS15::InitTimingTask()
{
	// timing update room info
    m_tmCSTrench = new CJoyTmCSTrench();
	m_tmCSTrench->m_room = this;
    if(!m_tmCSTrench->Create(this))
    {
        return false;
    }

    return true;
}

void CJoyMainRoom_CS15::FreeTimingTask()
{
	// timing update room info
    if(m_tmCSTrench != NULL)
    {
        m_tmCSTrench->Destroy();
        delete m_tmCSTrench;
        m_tmCSTrench = NULL;
    }
}

bool CJoyMainRoom_CS15::BroadcastMsg(CJoyTransmitData* data, CCSSvrIdList &csSvrExpt)
{
	POSITION pos = m_userIds.GetStartPosition();
    while(pos != NULL)
    {
        CJoyUser* pJoyUser;
        UINT userId;
        m_userIds.GetNextAssoc(pos, userId, pJoyUser);
        CJoyMainUser* pUser = (CJoyMainUser*)pJoyUser;
        if(pUser->m_status != UserStatus_Normal || !pUser->m_inRoom)
        {
            continue;
        }
		UINT nMapCount = 0;
		if (csSvrExpt.Lookup(pUser->m_userId, nMapCount))
		{
			continue;
		}
        pUser->SendMsg(data);
    }
    return true;
}

} // namespace JoyServer